package main

import "fmt"

func main() {
	/*
		1.方法：method
			一个方法就是一个包含了接收者的函数，接受者可以是命名类型或者结构体类型的一个值或者是一个指针。
			所有给定类型的方法属于该类型的方法集

		2.语法：
			func (接受者) 方法名(参数列表)(返回值列表) {

			}

		3.总结：method，同函数类似，区别是需要有接受者（也就是调用者）

		4.对比函数：
			A: 意义
				方法：某个类别的行为功能，需要指定的接受者调用
				函数：一段独立功能的代码，可以直接调用
			B: 语法
				方法：方法名可以相同，只要接受者不同
				函数：命名不能冲突

		5.无论是类型变量还是指针变量，都可以调用类型的所有方法

		  	T：接收者的值类型   			*T：接收者的指针类型
		  	S：接收者是值类型的方法集 		*S：接收者是指针类型的方法集
		  但是通过类型字面量显式地进行值调用和表达式调用时：
			T 只能调用 S
			*T 能调用 S 和 *S

	*/
	//结构体类型
	w1 := Worker1{"喜羊羊", 18, "男"}
	w1.work()
	w1.rest()

	//结构体指针类型
	w2 := &Worker1{"灰太狼", 36, "男"}
	fmt.Printf("%T\n", w2) //*main.Worker1
	w2.work()
	w2.rest()

	w2.printInfo()
	c1 := Cat{"白色的", 1}
	c1.printInfo()
}

// 1.定义一个工人结构体
type Worker1 struct {
	//字段
	name string
	age  int
	sex  string
}

type Cat struct {
	color string
	age   int
}

// 2.定义行为方法
func (w Worker1) work() { //w = w1
	fmt.Println(w.name, "在工作。。。")
}

func (p *Worker1) rest() { // p = w2, p = w1的地址
	fmt.Println(p.name, "在休息。。。")
}

func (p *Worker1) printInfo() {
	fmt.Printf("工人姓名：%s，工人年龄：%d，工人性别：%s\n", p.name, p.age, p.sex)
}

func (p *Cat) printInfo() {
	fmt.Printf("猫的颜色：%s，猫的年龄：%d\n", p.color, p.age)
}
